package com.yonder.testunsafe;

import com.py.tools.UnsafeTools;

import sun.misc.Unsafe;

/**
 * Unsafe在项目中要慎用、java9已经不再提供Unsafe支持
 * 
 * @author cyd
 * @date 2018年9月10日
 */
public class Test {

	private static final Unsafe unsafe = UnsafeTools.getUnsafe();
	private static final long valueOffset;

	private volatile long value;
	
	public Test(long val) {
		this.value = val;
	}
	
	public Test() {
	}
	
	static {
		try {
			valueOffset = unsafe.objectFieldOffset(Test.class.getDeclaredField("value"));
		} catch (Exception ex) {
			throw new Error(ex);
		}
	}

	public static void main(String[] args) {
		try {
			Test t = Test.class.newInstance();//在没有Test()构造函数时报错
			System.out.println(t.value);
			Test tt = (Test)unsafe.allocateInstance(Test.class);//不管有没有Test()都能正常运行
			System.out.println(tt.value);
			System.out.println(unsafe.shouldBeInitialized(Test.class));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		int testNum = 10;
		for (int i = 0; i < testNum; i++) {
			test1();
		}
		System.out.println("===================");
		for (int i = 0; i < testNum; i++) {
			test2();
		}
	}
	
	public static long test1() {//结果正确性不能保证
		Test t = new Test(0);
		for (int i = 0; i < 100; i++) {
			new Thread(()->{
				try {
					Thread.sleep(100);
				} catch (Exception e) {
					e.printStackTrace();
				}
				t.value++;
			}).start();
		}
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(t.value);
		return t.value;
	}
	
	public static long test2() {//保证结果正确
		Test t = new Test(0);
		for (int i = 0; i < 100; i++) {
			new Thread(()->{
				try {
					Thread.sleep(100);
				} catch (Exception e) {
					e.printStackTrace();
				}
				for (;;) {
					long val = t.value;
					if (unsafe.compareAndSwapLong(t, valueOffset, val, val + 1)) {
						break;
					}
				}
			}).start();
		}
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(t.value);
		return t.value;
	}
}
